package at.ac.tuwien.sepm.s2011.e0208329.gui;

import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import at.ac.tuwien.sepm.s2011.e0208329.domain.Dienstleistung;
import at.ac.tuwien.sepm.s2011.e0208329.domain.Rechnung;
import at.ac.tuwien.sepm.s2011.e0208329.services.MyBillServiceImpl;
import at.ac.tuwien.sepm.s2011.e0208329.services.MyCarServicesImpl;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;

@SuppressWarnings("serial")
public class MainUI extends JPanel {
	private static final Logger log = Logger.getLogger(MainUI.class);
	JTable[] jTableList;
	Vector<String> serviceColumns;
	Vector<String> billColumns;
	int selectedRowService = -1;
	int selectedRowBill = -1;

	public MainUI() {
		super(new GridLayout(1, 1));
		jTableList = new JTable[2];
		JTabbedPane tabbedPane = new JTabbedPane();
		serviceColumns = new Vector<String>();
		billColumns = new Vector<String>();
		serviceColumns.addAll(Arrays.asList("Dienstleistung ID",
				"Name", "Preis", "MwSt", "Techniker", "Aufwand", "Verkaufszahl"));
		billColumns.addAll(Arrays.asList("Rechnung ID", "Kundenname", "Adresse"));
		Vector<String> buttonNames1 = new Vector<String>();
		buttonNames1.addAll(Arrays.asList("Dienstleistung anlegen", "DIENSTLEISTUNG LOESCHEN",  "Alle Dienstleistungen anzeigen"));
		
		Vector<String> buttonNames2 = new Vector<String>();
		buttonNames2.addAll(Arrays.asList("Rechnung erstellen", "Bestellungen hinzufuegen","Ausgewaehlte Rechnung anzeigen", "Alle Rechnungen anzeigen", "Rechnung anzeigen"));		
		JComponent serviceTable = makeTable(serviceColumns, buttonNames1, 0);
		JComponent billTable = makeTable(billColumns, buttonNames2, 1);
		// JComponent servicePanel =
		// makeTextPanel("Service will be shown here");
		tabbedPane.addTab("Dienstleistung", null, serviceTable,
				"Dienstleistung verwalten");
		tabbedPane.addTab("Rechnung", null, billTable, "Rechnungen verwalten");

		// Add the tabbed pane to this panel.
		add(tabbedPane);

		// The following line enables to use scrolling tabs.
		tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
	}

	private JComponent makeTable(Vector<String> columnNames, Vector<String> buttonNames, int index) {
		JPanel panel = new JPanel(new GridLayout(2,1,50,50));
		JTable table = new JTable();
		table.setModel(new DefaultTableModel(columnNames, 10));
		table.setPreferredScrollableViewportSize(new Dimension(800, 175));
		table.setFillsViewportHeight(true);
		jTableList[index] = table;
		JScrollPane scrollPane = new JScrollPane(table);
		panel.add(scrollPane);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		if (index == 0) {
	        ListSelectionModel rowSMService = table.getSelectionModel();
	        rowSMService.addListSelectionListener(new ListSelectionListener() {
	            public void valueChanged(ListSelectionEvent e) {
	                //Ignore extra messages.
	                if (e.getValueIsAdjusting()) return;

	                ListSelectionModel lsm = (ListSelectionModel)e.getSource();
	                if (lsm.isSelectionEmpty()) {
	                    log.info("No service row is selected.");
	                } else {
	                	MainUI.this.selectedRowService = lsm.getMinSelectionIndex();
	                    log.info("Service row selected = " + MainUI.this.selectedRowService);
	                }
	            }
	        });
		} else {
	        ListSelectionModel rowSMBill = table.getSelectionModel();
	        rowSMBill.addListSelectionListener(new ListSelectionListener() {
	            public void valueChanged(ListSelectionEvent e) {
	                //Ignore extra messages.
	                if (e.getValueIsAdjusting()) return;

	                ListSelectionModel lsm = (ListSelectionModel)e.getSource();
	                if (lsm.isSelectionEmpty()) {
	                    log.info("No bill row is selected.");
	                } else {
	                	MainUI.this.selectedRowBill = lsm.getMinSelectionIndex();
	                    log.info("Bill row selected = " + MainUI.this.selectedRowBill);
	                }
	            }
	        });
			
		}

		
		JPanel buttonPanel = new JPanel(new FlowLayout());
		for (String name: buttonNames) {
			if (name.equals("Dienstleistung anlegen")) {
				ActionListener dienstAnlegenListener = new ActionListener() {
					public void actionPerformed(ActionEvent actionEvent) {
						log.debug("Dienstleistung anlegen clicked");
						new CreateServiceUI("Neue Dienstleistung anlegen");
					}
				};
				
				JButton myButton = new JButton(name);
				myButton.addActionListener(dienstAnlegenListener);
				buttonPanel.add(myButton);
			}
			
			if (name.equals("Dienstleistung bearbeiten")) {
				ActionListener dienstAnlegenListener = new ActionListener() {
					public void actionPerformed(ActionEvent actionEvent) {
						log.debug("Dienstleistung bearbeiten clicked");
					}
				};
				
				JButton myButton = new JButton(name);
				myButton.addActionListener(dienstAnlegenListener);
				buttonPanel.add(myButton);
			}
			
			if (name.equals("DIENSTLEISTUNG LOESCHEN")) {
				ActionListener dienstAnlegenListener = new ActionListener() {
					public void actionPerformed(ActionEvent actionEvent) {
						log.debug("Dienstleistung loeschen clicked");
						if (MainUI.this.selectedRowService == -1) {
							JOptionPane.showMessageDialog(null,
									 "You need to select a service first !","Selection error",
									JOptionPane.ERROR_MESSAGE);
						} else {
							delSelectedService(MainUI.this.selectedRowService);
						}
						
						
					}
				};
				
				JButton myButton = new JButton(name);
				myButton.addActionListener(dienstAnlegenListener);
				buttonPanel.add(myButton);
			}
			
			if (name.equals("Suchen")) {
				ActionListener dienstAnlegenListener = new ActionListener() {
					public void actionPerformed(ActionEvent actionEvent) {
						log.debug("Suchen clicked");
					}
				};
				
				JButton myButton = new JButton(name);
				myButton.addActionListener(dienstAnlegenListener);
				buttonPanel.add(myButton);
			}
			
			if (name.equals("Alle Dienstleistungen anzeigen")) {
				ActionListener ShowServiceListener = new ActionListener() {
					public void actionPerformed(ActionEvent actionEvent) {
						log.debug("Alle Dienstleistung anzeigen clicked");
						ArrayList<Dienstleistung> services;
						try {
							services = MyCarServicesImpl.getInstance().getAllServices();// do the select * from database
							log.debug("Number of services = " + services.size());
							updateServiceTable(services);	// print
						} catch (SQLException e) {
							log.error(e.getMessage());
							JOptionPane.showMessageDialog(null,
									"Please see log file for more detail !", "SQL error",
									JOptionPane.ERROR_MESSAGE);
						}
					
					}
				};
				
				JButton myButton = new JButton(name);
				myButton.addActionListener(ShowServiceListener);
				buttonPanel.add(myButton);
			}
			
			if (name.equals("Rechnung erstellen")) {
				ActionListener CreateBillListener = new ActionListener() {
					public void actionPerformed(ActionEvent actionEvent) {
						log.debug("Rechnung erstellen clicked");
						new CreateBillUI("Neue Rechnung erstellen");
					}
				};
				
				JButton myButton = new JButton(name);
				myButton.addActionListener(CreateBillListener);
				buttonPanel.add(myButton);
			}
						
			if (name.equals("Ausgewaehlte Rechnung anzeigen")) {
				ActionListener CreateBillListener = new ActionListener() {
					public void actionPerformed(ActionEvent actionEvent) {
						log.debug("Ausgewaehlte Rechnung anzeigen clicked");
						if (MainUI.this.selectedRowBill == -1) {//no rows selected
							JOptionPane.showMessageDialog(null,
									 "You need to select a bill first !","Selection error",
									JOptionPane.ERROR_MESSAGE);
						} else {
							Vector<String> cusInfo = getBillInfoFromRow(MainUI.this.selectedRowBill);// read row's content
							log.debug("ID of the selected bill is " + cusInfo.get(0));
							new ShowBill("Rechnungsinformation", Integer.parseInt(cusInfo.get(0)), cusInfo.get(1), cusInfo.get(2));
						}
					}
				};
				
				JButton myButton = new JButton(name);
				myButton.addActionListener(CreateBillListener);
				buttonPanel.add(myButton);
			}
			
			if (name.equals("Alle Rechnungen anzeigen")) {
				ActionListener ShowBillListener = new ActionListener() {
					public void actionPerformed(ActionEvent actionEvent) {
						log.debug("Rechnung anzeigen clicked");
						ArrayList<Rechnung> bills;
						try {
							bills = MyBillServiceImpl.getInstance().getBills();// read all bills from database
							updateBillTable(bills); // print
						} catch (SQLException e) {
							log.error(e.getMessage());
							JOptionPane.showMessageDialog(null,
									"Please see log file for more detail !", "SQL error",
									JOptionPane.ERROR_MESSAGE);
						}						
					}
				};
				
				JButton myButton = new JButton(name);
				myButton.addActionListener(ShowBillListener);
				buttonPanel.add(myButton);
			}
			
			if (name.equals("Bestellungen hinzufuegen")) {
				ActionListener dienstAnlegenListener = new ActionListener() {
					public void actionPerformed(ActionEvent actionEvent) { //Listen the Action, when done, perform
						log.debug("Bestellungen zum Rechnung hinzufuegen clicked");
						if (MainUI.this.selectedRowBill == -1) {// if no rows selected
							JOptionPane.showMessageDialog(null,
									 "You need to select a bill first !","Selection error",
									JOptionPane.ERROR_MESSAGE);
						} else {// row selected
							Vector<String> cusInfo = getBillInfoFromRow(MainUI.this.selectedRowBill);// read the row's content as Vector<String>
							log.debug("ID of the selected bill is " + cusInfo.get(0));
							new AddOrdersUI("Bestellung bearbeiten", Integer.parseInt(cusInfo.get(0)), cusInfo.get(1), cusInfo.get(2));
						}
						
						//new AddOrdersUI("Bestellung bearbeiten", billID, cusName, cusAdress)
					}
				};
				
				JButton myButton = new JButton(name);
				myButton.addActionListener(dienstAnlegenListener);
				buttonPanel.add(myButton);
			}
		}	
		panel.add(buttonPanel);
		return panel;

	}

	protected void updateBillTable(ArrayList<Rechnung> bills) {// print the bill's table
		JTable billTable = jTableList[1];
		billTable.setModel(new DefaultTableModel(billColumns, 10));
		DefaultTableModel tableModel = (DefaultTableModel) billTable.getModel();
		billTable.repaint();
		String[] data = new String[tableModel.getColumnCount()];
		int rowNr = 0;
		for (Rechnung bill : bills) {
			data[0] = Integer.toString(bill.getIdBill());
			data[1] = bill.getCustomerName();
			data[2] = bill.getAddress();
			tableModel.insertRow(rowNr, data);
			rowNr++;
		}
		billTable.setModel(tableModel);
		
	}

	protected Vector<String> getBillInfoFromRow(int rowID) { // read the bill infos
		JTable billTable = jTableList[1];
		DefaultTableModel tabModel = (DefaultTableModel) billTable.getModel();
		@SuppressWarnings("unchecked")
		Vector<String> myRow = (Vector<String>) tabModel.getDataVector().elementAt(rowID);
		return myRow;		
	}
	
	protected void delSelectedService(int rowID) {
		JTable serviceTable = jTableList[0];
		DefaultTableModel tableModel = (DefaultTableModel) serviceTable.getModel();
		@SuppressWarnings("unchecked")
		Vector<String> myRow = (Vector<String>) tableModel.getDataVector().elementAt(rowID);
		int mySerID = Integer.parseInt(myRow.get(0)); //get the Service's ID
		log.debug("Deleting service with ID = " + mySerID);
		try {
			MyCarServicesImpl.getInstance().deleteService(mySerID);// do the delete action
			JOptionPane.showMessageDialog(null,
					 "Service " + myRow.get(1) + " has been successfully deleted","Deletion confirmation",
					JOptionPane.INFORMATION_MESSAGE);	
		} catch (SQLException e) {
			log.error(e.getMessage());
			JOptionPane.showMessageDialog(null,
					 "SQL error: see log !","SQL error",
					JOptionPane.ERROR_MESSAGE);	
		}
		
		
	}

	protected void updateServiceTable(ArrayList<Dienstleistung> services) { // print the List of Services
		JTable serviceTable = jTableList[0];
		serviceTable.setModel(new DefaultTableModel(serviceColumns, 10));
		DefaultTableModel tableModel = (DefaultTableModel) serviceTable.getModel();
		serviceTable.repaint();
		String[] data = new String[tableModel.getColumnCount()];
		int rowNr = 0;
		for (Dienstleistung ser : services) {
			data[0] = Integer.toString(ser.getIdService());
			data[1] = ser.getName();
			data[2] = Double.toString(ser.getPrice());
			data[3] = Double.toString(ser.getTax());
			data[4] = ser.getTechnician();
			data[5] = Double.toString(ser.getTimeRequired());
			data[6] = Integer.toString(ser.getSaleNumber());
			tableModel.insertRow(rowNr, data);
			rowNr++;
		}
		serviceTable.setModel(tableModel);		
	}

	/**
	 * Create the GUI and show it. For thread safety, this method should be
	 * invoked from the event dispatch thread.
	 */
	private static void createAndShowGUI() {
		// Create and set up the window.
		JFrame frame = new JFrame("Autowerkstatt");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// Add content to the window.
		frame.add(new MainUI(), BorderLayout.NORTH);
		// Display the window.
		frame.pack();
		frame.setVisible(true);
	}

	public static void main(String[] args) {
		PropertyConfigurator.configure("log4j.properties");
		// Schedule a job for the event dispatch thread:
		// creating and showing this application's GUI.
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				// Turn off metal's use of bold fonts
				UIManager.put("swing.boldMetal", Boolean.FALSE);
				createAndShowGUI();
			}
		});
	}
}
